import socket
import time
import threading
import queue

REMOTE_ADDR = "10.0.1.6"
REMOTE_PORT = 6780

MULTI_ADDR = "239.255.0.6"

LOCAL_ADDR = "10.0.1.10"
LOCAL_PORT = 6780

FRAME_SIZE = 16


class eth():
	def __init__(self, sock: socket.socket):
		self.sock = sock
		self.counter = 0
		self.comid = 13006
		pass

	def send(self, id: int, data: bytes):
		if len(data) > 8:
			raise "data length exceed range (8)"
		# data set
		buf = id.to_bytes(4, "little") + len(data).to_bytes(4, "little") + data
		buf += bytes(8 - len(data))

		self.sock.sendto(buf, (REMOTE_ADDR, REMOTE_PORT))
		pass


class rcv(threading.Thread):
	def __init__(self, name: str, sock: socket.socket) -> None:
		super().__init__(name=name, daemon=True)
		self.sock = sock
		self.starttime = time.time()



	def run(self) -> None:
		while True:
			buf = self.sock.recv(120)
			if len(buf) < FRAME_SIZE:
				print("recv length too short")
				continue
			id = int.from_bytes(buf[0:4], "little")
			leng = int.from_bytes(buf[4:8], "little")
			if leng > 8:
				print("got incorrect can frame")
				continue
			data = buf[8:8 + leng]
			print("from ", len(buf), "bytes got: id 0x", id.hex(), ", data ", data.hex(), ", len ", leng, ", time ", time.time()-self.starttime)
			if leng == 0:
				print(buf.hex())


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((LOCAL_ADDR, LOCAL_PORT))
ethport = eth(sock)
sock_multi = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock_multi.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock_multi.bind((LOCAL_ADDR, LOCAL_PORT))
sock_multi.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
sock_multi.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(MULTI_ADDR) + socket.inet_aton(LOCAL_ADDR))
recv = rcv("recv", sock_multi)
print("sending message")
recv.start()
while True:
	ethport.send(0x11223344, b"hello")
	time.sleep(1)
	pass
